#pragma semicolon 1
#include <sourcemod>
#include <sdktools>
#include <adminmenu>

#define IsValidClient(%1)  ( 1 <= %1 <= MaxClients && IsClientInGame(%1) )
#define PLUGIN_VERSION "1.1"

new Handle:hTopMenu = INVALID_HANDLE;
new TopMenuObject:explosive_ammo;
new TopMenuObject:incendiary_ammo;
new TopMenuObject:give_health;
new TopMenuObject:give_first_kit;
new TopMenuObject:teleport;
new TopMenuObject:laserAndmelee;
new TopMenuObject:miniguns;

new c_id[MAXPLAYERS+1];
new g_id[MAXPLAYERS+1];

public Plugin:myinfo =
{
	name = "L4D2管理员娱乐菜单", author = "蛋疼哥", description = "QQ群:86232128", version = PLUGIN_VERSION, url = "N/A"
};

public OnPluginStart()
{ 
	RegAdminCmd("sm_yule", AdminFunCommand, ADMFLAG_KICK);
	RegAdminCmd("sm_dtg", AdminFunCommand, ADMFLAG_KICK);
	
	if (LibraryExists("adminmenu") && ((hTopMenu = GetAdminTopMenu()) != INVALID_HANDLE))
	{
		OnAdminMenuReady(hTopMenu);
	}
	
	CreateConVar("L4d2_AdminFunCommand_Version", PLUGIN_VERSION, "插件版本", FCVAR_NOTIFY);
}

/* Admin Functions */
public OnLibraryRemoved(const String:name[])
{
	if (StrEqual(name, "adminmenu"))
	{
		hTopMenu = INVALID_HANDLE;
	}
}

public OnAdminMenuReady(Handle:topmenu)
{
	// Check ..
	if (topmenu == hTopMenu) return;
	
	// We save the handle
	hTopMenu = topmenu;
	AddToTopMenu(hTopMenu, "Fun Command", TopMenuObject_Category, Menu_CategoryHandler, INVALID_TOPMENUOBJECT);
	
	// Find admin menu ...
	new TopMenuObject:AdminTopmenu = FindTopMenuCategory(hTopMenu, "Fun Command");
	
	// now we add the function ...
	if (AdminTopmenu == INVALID_TOPMENUOBJECT) return;
	explosive_ammo	= AddToTopMenu(hTopMenu, "explosive_ammo", TopMenuObject_Item, Menu_TopItemHandler, AdminTopmenu, "explosive_ammo", ADMFLAG_KICK);
	incendiary_ammo	= AddToTopMenu(hTopMenu, "incendiary_ammo", TopMenuObject_Item, Menu_TopItemHandler, AdminTopmenu, "incendiary_ammo", ADMFLAG_KICK);
	give_health		= AddToTopMenu(hTopMenu, "give_health", TopMenuObject_Item, Menu_TopItemHandler, AdminTopmenu, "give_health", ADMFLAG_KICK);
	give_first_kit	= AddToTopMenu(hTopMenu, "give_first_kit", TopMenuObject_Item, Menu_TopItemHandler, AdminTopmenu, "give_first_kit", ADMFLAG_KICK);
	teleport		= AddToTopMenu(hTopMenu, "teleport", TopMenuObject_Item, Menu_TopItemHandler, AdminTopmenu, "teleport", ADMFLAG_KICK);
	laserAndmelee	= AddToTopMenu(hTopMenu, "laserAndmelee", TopMenuObject_Item, Menu_TopItemHandler, AdminTopmenu, "laserAndmelee", ADMFLAG_KICK);
	miniguns		= AddToTopMenu(hTopMenu, "miniguns", TopMenuObject_Item, Menu_TopItemHandler, AdminTopmenu, "miniguns", ADMFLAG_KICK);
}

public Menu_CategoryHandler(Handle:topmenu, TopMenuAction:action, TopMenuObject:object_id, Client, String:buffer[], maxlength)
{
	if (action == TopMenuAction_DisplayTitle)
		Format(buffer, maxlength, "选择功能");
	else if (action == TopMenuAction_DisplayOption)
		Format(buffer, maxlength, "L4D2管理员娱乐菜单");
}

public Menu_TopItemHandler(Handle:topmenu, TopMenuAction:action, TopMenuObject:object_id, Client, String:buffer[], maxlength) 
{
	if (action == TopMenuAction_DisplayOption) {
		if (object_id == explosive_ammo) {
			Format(buffer, maxlength, "高爆弹");
		} else if (object_id == incendiary_ammo) {
			Format(buffer, maxlength, "燃烧弹");
		} else if (object_id == give_health) {
			Format(buffer, maxlength, "润滑油");
		} else if (object_id == give_first_kit) {
			Format(buffer, maxlength, "药包等");
		} else if (object_id == teleport) {
			Format(buffer, maxlength, "传送门");
		} else if (object_id == laserAndmelee) {
			Format(buffer, maxlength, "激光刀");
		} else if (object_id == miniguns) {
			Format(buffer, maxlength, "机关枪");
		}
	} 
	else if (action == TopMenuAction_SelectOption) 
	{
		if (object_id == explosive_ammo) {
			CheatCommand(Client, "upgrade_add", "explosive_ammo");
			SuperAdminMenu(Client);
		} else if (object_id == incendiary_ammo) {
			CheatCommand(Client, "upgrade_add", "incendiary_ammo");
			SuperAdminMenu(Client);
		} else if (object_id == give_health) {
			CheatCommand(Client, "give", "health");
			SuperAdminMenu(Client);
		} else if (object_id == give_first_kit) {
			g_id[Client]=1;
			GiveID(Client);
		} else if (object_id == teleport) {
			g_id[Client]=3;
			GiveID(Client);
		} else if (object_id == laserAndmelee) {
			CheatCommand(Client, "upgrade_add", "laser_sight");
			CheatCommand(Client, "give", "machete");
			CheatCommand(Client, "give", "katana");
			SuperAdminMenu(Client);
		} else if (object_id == miniguns) {
			g_id[Client]=2;
			GiveID(Client);
		}	
	}
}

public Action:AdminFunCommand(Client, args)
{
	if (IsValidClient(Client)) SuperAdminMenu(Client);
	return Plugin_Handled;
}

SuperAdminMenu(Client)
{
	new Handle:menu = CreateMenu(SuperAdminMenu_MenuHandler);
	/* if (SuperAdmin[Client]) {SetMenuTitle(menu, "Ver:%s, RCON:%s", TimeVer, currentRcon);
	} else */
	SetMenuTitle(menu, "请选择");
	AddMenuItem(menu, "option1", "高爆弹");
	AddMenuItem(menu, "option2", "燃烧弹");
	AddMenuItem(menu, "option3", "润滑油");
	AddMenuItem(menu, "option4", "药包等");
	AddMenuItem(menu, "option5", "传送门");
	AddMenuItem(menu, "option6", "激光刀");
	AddMenuItem(menu, "option7", "机关枪");
	
	SetMenuExitButton(menu, true);
	DisplayMenu(menu, Client, 20);
}

public SuperAdminMenu_MenuHandler(Handle:menu, MenuAction:action, Client, itemNum)
{
	if(action == MenuAction_Select) {
		switch(itemNum) {
			case 0: {
				CheatCommand(Client, "upgrade_add", "explosive_ammo");
				SuperAdminMenu(Client);
			} case 1: {
				CheatCommand(Client, "upgrade_add", "incendiary_ammo");
				SuperAdminMenu(Client);
			} case 2: {
				CheatCommand(Client, "give", "health");
				SuperAdminMenu(Client);
			} case 3: {
				g_id[Client]=1;
				GiveID(Client);
			} case 4: {
				g_id[Client]=3;
				GiveID(Client);
			} case 5: {
				CheatCommand(Client, "upgrade_add", "laser_sight");
				CheatCommand(Client, "give", "machete");
				CheatCommand(Client, "give", "katana");
				SuperAdminMenu(Client);
			} case 6: {
				g_id[Client]=2;
				GiveID(Client);
			}
		}
	}
}

GiveID(Client)
{
	new Handle:menu = CreateMenu(GiveID_MenuHandler);
	/* if (SuperAdmin[Client]) {SetMenuTitle(menu, "RCON:%s", currentRcon);
	} else */
	SetMenuTitle(menu, "请选择");
	if (g_id[Client]==1) {
		AddMenuItem(menu, "option1", "药包");
		AddMenuItem(menu, "option2", "电击");
		AddMenuItem(menu, "option3", "针管");
		AddMenuItem(menu, "option4", "火瓶");
		AddMenuItem(menu, "option5", "胆汁");
	} else if (g_id[Client]==2) {
		AddMenuItem(menu, "option1", "创建");
		AddMenuItem(menu, "option2", "移除");
	} else if (g_id[Client]==3) {
		AddMenuItem(menu, "option1", "随机传送");
		AddMenuItem(menu, "option2", "鼠标所指");
		AddMenuItem(menu, "option3", "传送至某");
		AddMenuItem(menu, "option4", "传送某至");
	}
	SetMenuExitBackButton(menu, true);
	SetMenuExitButton(menu, true);
	DisplayMenu(menu, Client, 20);
}
public GiveID_MenuHandler(Handle:menu, MenuAction:action, Client, itemNum) {
	if (action == MenuAction_End) {
		CloseHandle(menu);
	} else if (action == MenuAction_Cancel) {
		SuperAdminMenu(Client);
	} else if(action == MenuAction_Select) {
		if (g_id[Client]==1) {
			switch(itemNum) {
				case 0: {
					c_id[Client]=1;
				} case 1: {
					c_id[Client]=2;
				} case 2: {
					c_id[Client]=3;
				} case 3: {
					c_id[Client]=4;
				} case 4: {
					c_id[Client]=5;
				}
			}
			GiveChoose(Client);
		} else if (g_id[Client]==2) {
			switch(itemNum) {
				case 0: {
					c_id[Client]=6;
				} case 1: {
					c_id[Client]=7;
				}
			}
			GiveChoose(Client);
		} else if (g_id[Client]==3) {
			switch(itemNum) {
				case 0: {
					c_id[Client]=8;
					GiveChoose(Client);
				} case 1: {
					c_id[Client]=9;
					GiveChoose(Client);
				} case 2: {
					c_id[Client]=10;
					TeleportTo(Client);
				} case 3: {
					c_id[Client]=11;
					TeleportTo(Client);
				}
			}
		}
		
	}
}
GiveChoose(Client) {
	if (c_id[Client]==1) {
		CheatCommand(Client, "give", "first_aid_kit");
		GiveID(Client);
	} else if (c_id[Client]==2) {
		CheatCommand(Client, "give", "defibrillator");
		GiveID(Client);
	} else if (c_id[Client]==3) {
		CheatCommand(Client, "give", "adrenaline");
		GiveID(Client);
	} else if (c_id[Client]==4) {
		CheatCommand(Client, "give", "molotov");
		GiveID(Client);
	} else if (c_id[Client]==5) {
		CheatCommand(Client, "give", "vomitjar");
		GiveID(Client);
	} else if (c_id[Client]==6) {
		SpawnMinigun(Client);
		GiveID(Client);
	} else if (c_id[Client]==7) {
		RemoveEntitys(Client);
		GiveID(Client);
	} else if (c_id[Client]==8) {
		RandomTeleport(Client);
		GiveID(Client);
	} else if (c_id[Client]==9) {
		AppointTeleport(Client);
		GiveID(Client);
	}
}

public Action:RandomTeleport(Client)
{
	decl Float:TeleportOrigin[3],Float:PlayerOrigin[3];
	new Player;
	for(new X = 1; X <= MaxClients; X++)
	{
		if(!IsClientConnected(X)) continue;
		if(GetClientTeam(X)!=2) continue;
		Player = X;
	}
	if(Player == -1) {
		ReplyToCommand(Client, "[SM]找不到传送目标!");
		return Plugin_Handled;
	}
	GetClientAbsOrigin(Player, PlayerOrigin);
	TeleportOrigin[0] = PlayerOrigin[0];
	TeleportOrigin[1] = PlayerOrigin[1];
	TeleportOrigin[2] = (PlayerOrigin[2]+1);//防止卡人
	TeleportEntity(Client, TeleportOrigin, NULL_VECTOR, NULL_VECTOR);
	return Plugin_Handled;
}
public Action:AppointTeleport(Client) {
	decl Float:position[3], Float:angles[3];
	if (GetClientAimedLocationData(Client, position, angles, NULL_VECTOR) == -1) {
		ReplyToCommand(Client, "[SM]目标不可达!");
		return Plugin_Handled;
	}
	TeleportEntity(Client, position, angles, NULL_VECTOR);
	return Plugin_Handled;
}
public Action:TeleportTo(Client)
{
	new Handle:menu = CreateMenu(TeleportTo_Handler);
	SetMenuTitle(menu, "选择传送");
	//AddTargetsToMenu2(menu, Client, COMMAND_FILTER_CONNECTED);
	decl String:user_id[12];
	decl String:display[MAX_NAME_LENGTH+12];
	for (new i = 1; i <= MaxClients; i++) {
		if (!IsValidEntity(i)) continue; 
		if (!IsClientConnected(i) || IsClientInKickQueue(i)) continue;
		if (!IsClientInGame(i)) continue;
		if (!IsPlayerAlive(i)) continue;
		if (c_id[Client]==10) {
			if (i==Client) continue;
		}
		Format(display, sizeof(display), "%N", i);
		IntToString(i, user_id, sizeof(user_id));
		AddMenuItem(menu, user_id, display);
	}
	SetMenuExitBackButton(menu, true);
	DisplayMenu(menu, Client, MENU_TIME_FOREVER);
}
public TeleportTo_Handler(Handle:menu, MenuAction:action, Client, param2)
{
	if (action == MenuAction_End) {
		CloseHandle(menu);
	} else if (action == MenuAction_Cancel) {
		GiveID(Client);
	} else if (action == MenuAction_Select)	{
		new String:info[56];
		GetMenuItem(menu, param2, info, sizeof(info));
		new target = StringToInt(info);
		if(target != -1) {
			if (c_id[Client]==10) {
				decl Float:TeleportOrigin[3],Float:PlayerOrigin[3];
				GetClientAbsOrigin(target, PlayerOrigin);
				TeleportOrigin[0] = PlayerOrigin[0];
				TeleportOrigin[1] = PlayerOrigin[1];
				TeleportOrigin[2] = (PlayerOrigin[2]+1);//防止卡人
				TeleportEntity(Client, TeleportOrigin, NULL_VECTOR, NULL_VECTOR);
			} else if (c_id[Client]==11) {
				decl Float:position[3], Float:angles[3];
				if (GetClientAimedLocationData(Client, position, angles, NULL_VECTOR) != -1) {
					if (IsClientInGame(target)) TeleportEntity(target, position, angles, NULL_VECTOR);
				}
			}
			TeleportTo(Client);
		}
	}
}

public Action:SpawnMinigun(Client) {
	new index = CreateEntity(Client, "prop_minigun", "minigun", "models/w_models/weapons/w_minigun.mdl");
	if (index != -1) {
		decl Float:position[3], Float:angles[3];
		if (GetClientAimedLocationData(Client, position, angles, NULL_VECTOR) == -1) {
			RemoveEdict(index);
			return Plugin_Handled;
		}
		angles[0] = 0.0;
		angles[2] = 0.0;
		DispatchKeyValueVector(index, "Origin", position);
		DispatchKeyValueVector(index, "Angles", angles);
		DispatchKeyValueFloat(index, "MaxPitch",  40.00);
		DispatchKeyValueFloat(index, "MinPitch", -30.00);
		DispatchKeyValueFloat(index, "MaxYaw",	90.00);
		DispatchSpawn(index);
	}
	return Plugin_Handled;
}
public Action:RemoveEntitys(Client) {
	new player = GetPlayerIndex(Client);
	new index = -1;
	index = GetClientAimedLocationData(Client, NULL_VECTOR, NULL_VECTOR, NULL_VECTOR);
	if (index > MaxClients) {
		RemoveEdict(index);
		ReplyToCommand(player, "[SM]实体被移除(编号: %i)", index);
	}
	return Plugin_Handled;
}
CreateEntity(Client, const String:entity_name[], const String:item_name[], const String:model[] = "") {
	new player = GetPlayerIndex(Client);
	if (player == 0) return -1;
	new index = CreateEntityByName( entity_name );
	if (index == -1)  {
		ReplyToCommand(player, "[SM]无法创建 %s !", item_name);
		return -1;
	}
	if (strlen(model) != 0) {
		if (!IsModelPrecached(model)) PrecacheModel(model);
		SetEntityModel(index, model);
	}
	ReplyToCommand(player, "[SM]成功创建%s(编号: %i)", item_name, index);
	return index;
}
GetClientAimedLocationData(Client, Float:position[3], Float:angles[3], Float:normal[3]) {
	new index = -1;
	new player = GetPlayerIndex(Client);
	decl Float:_origin[3], Float:_angles[3];
	GetClientEyePosition(player, _origin);
	GetClientEyeAngles(player, _angles);
	new Handle:trace = TR_TraceRayFilterEx(_origin, _angles, MASK_SOLID_BRUSHONLY, RayType_Infinite, TraceEntityFilterPlayers);
	if (!TR_DidHit(trace)) { 
		ReplyToCommand( player, "[SM]无效的目标" );
		index = -1;
	} else {
		TR_GetEndPosition(position, trace);
		TR_GetPlaneNormal(trace, normal);
		angles[0] = _angles[0];
		angles[1] = _angles[1];
		angles[2] = _angles[2];
		index = TR_GetEntityIndex(trace);
	} CloseHandle(trace);
	return index;
}
GetPlayerIndex(Client) {
	if (Client== 0 && !IsDedicatedServer()) return 1;
	return Client;
}
public bool:TraceEntityFilterPlayers(entity, contentsMask, any:data) {return entity > MaxClients && entity != data;}

stock CheatCommand(Client, const String:command[], const String:arguments[]) {
	if (!Client) return;
	new admindata = GetUserFlagBits(Client);
	SetUserFlagBits(Client, ADMFLAG_ROOT);
	new flags = GetCommandFlags(command);
	SetCommandFlags(command, flags & ~FCVAR_CHEAT);
	FakeClientCommand(Client, "%s %s", command, arguments);
	SetCommandFlags(command, flags);
	SetUserFlagBits(Client, admindata);
}